package com.ihr360.payroll.service.salaryreport.job;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.commons.lang.DateUtils;
import com.ihr360.commons.lang.StringUtils;
import com.ihr360.commons.model.meta.table.DynamicCell;
import com.ihr360.commons.model.type.FieldSource;
import com.ihr360.commons.model.type.SalaryFieldValueType;
import com.ihr360.payroll.dao.HistoryPayPeriodRepository;
import com.ihr360.payroll.dao.MergeReportStaffSalaryRepository;
import com.ihr360.payroll.dao.MergeReportWithSalaryPlanRepository;
import com.ihr360.payroll.dao.MergeSalaryReportRepository;
import com.ihr360.payroll.dao.MergeSalaryReportTermSalaryRepository;
import com.ihr360.payroll.dao.StaffPayPeriodTermSalaryRepository;
import com.ihr360.payroll.model.dto.salary.report.HistoryPayPeriod;
import com.ihr360.payroll.model.dto.salary.report.HistorySalaryPlan;
import com.ihr360.payroll.model.dto.salary.report.MergeReportStaffSalary;
import com.ihr360.payroll.model.dto.salary.report.MergeReportWithSalaryPlan;
import com.ihr360.payroll.model.dto.salary.report.MergeSalaryReport;
import com.ihr360.payroll.model.dto.salary.report.MergeSalaryReportTermSalary;
import com.ihr360.payroll.model.dto.salary.report.embedded.SalaryFieldSnapshot;
import com.ihr360.payroll.model.dto.salary.task.period.PayPeriodTerm;
import com.ihr360.payroll.model.dto.salary.task.period.StaffPayPeriodTermSalary;
import com.ihr360.payroll.model.dto.salary.task.period.embeddable.StaffSalarySnapshot;
import com.ihr360.payroll.model.dto.salary.task.period.embeddable.StaffSalarySnapshotListWrapper;
import com.ihr360.payroll.model.dto.salary.task.period.embeddable.StaffSalaryTermId;
import com.ihr360.payroll.model.response.salaryreport.SalaryHeader;
import com.ihr360.payroll.model.vo.SalaryFieldEntity;
import com.ihr360.payroll.service.salaryreport.impl.HistorySalaryPlanServiceImpl;
import com.ihr360.payroll.type.ReportState;
import com.ihr360.shared.basicstaffinfo.dto.SyncedBasicStaffInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created by Eric on 2018/4/10/010.
 * 合并报表异步计算任务
 */
@Component
public class MergeSalaryReportDataJob {

    private static Logger logger = LoggerFactory.getLogger(MergeSalaryReportDataJob.class);

    @Autowired
    private MergeReportWithSalaryPlanRepository mergeReportWithSalaryPlanRepository;

    @Autowired
    private MergeSalaryReportRepository mergeSalaryReportRepository;

    @Autowired
    private HistoryPayPeriodRepository historyPayPeriodRepository;

    @Autowired
    private MergeReportStaffSalaryRepository mergeReportStaffSalaryRepository;

    @Autowired
    private StaffPayPeriodTermSalaryRepository staffPayPeriodTermSalaryRepository;

    @Autowired
    private MergeSalaryReportTermSalaryRepository mergeSalaryReportTermSalaryRepository;

    @Autowired
    private EntityManager entityManager;

    public void calMergeReport(String companyId, HistoryPayPeriod historyPayPeriod) {
        if (historyPayPeriod == null) {
            logger.error("账期数据为null,结束计算，公司id：" + companyId);
            return;
        }
        if (historyPayPeriod.getSalaryPlan() == null) {
            logger.error("账期关联薪资方案快照为空,结束计算");
            logger.error("历史账期参数：historyPayPeriodId:" + historyPayPeriod.getId());
            return;
        }
        Long salaryPlanId = historyPayPeriod.getSalaryPlan().getSalaryPlanId();
        //首先查询关账的薪酬账期关联的薪资方案 是否有合并报表关联该薪资方案
        List<MergeReportWithSalaryPlan> planIdList = mergeReportWithSalaryPlanRepository.findByCompanyIdAndSalaryPlanId(companyId, salaryPlanId);
        List<MergeSalaryReport> mergeSalaryReportList = planIdList.stream().map(MergeReportWithSalaryPlan::getMergeReport).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(mergeSalaryReportList)) {
            logger.info("该薪资方案未关联合并报表,无需计算");
            logger.info("历史账期参数：historyPayPeriodId:" + historyPayPeriod.getId());
            return;
        }
        Date termDate = historyPayPeriod.getStartOn();
        //重新计算合并报表结果数据
        List<PayPeriodTerm> payPeriodTermList = historyPayPeriod.getTerms();
        if (CollectionUtils.isEmpty(payPeriodTermList)) {
            logger.info("该薪资方案数据为空,无需计算");
            logger.info("历史账期参数：historyPayPeriodId:" + historyPayPeriod.getId());
            return;
        }
        List<Long> mergeReportIdList = mergeSalaryReportList.stream().map(MergeSalaryReport::getId).collect(Collectors.toList());
        List<Integer> indexList = payPeriodTermList.stream().map(PayPeriodTerm::getTermIndex).collect(Collectors.toList());
        int year = Integer.parseInt(DateUtils.formatDateStr(termDate, DateUtils.STANDARD_DATE_FORMAT_Y));
        int month = Integer.parseInt(DateUtils.formatDateStr(termDate, DateUtils.STANDARD_DATE_FORMAT_M));
        List<MergeSalaryReportTermSalary> mergeSalaryReportTermSalaryList = mergeSalaryReportTermSalaryRepository.findByCompanyIdAndMergeReportIdInAndYearAndMonthAndIndexnoIn(companyId, mergeReportIdList, year, month, indexList);
        Map<String, MergeSalaryReportTermSalary> termSalaryMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(mergeSalaryReportTermSalaryList)) {
            mergeSalaryReportTermSalaryList.forEach(mergeSalaryReportTermSalary -> {
                mergeSalaryReportTermSalary.setReportState(ReportState.STARTED);
                mergeSalaryReportTermSalary.setSalaryHeader(null);
            });
            logger.info("--------修改已存在的合并报表数据状态");
            termSalaryMap = mergeSalaryReportTermSalaryList.stream().collect(Collectors.toMap(term -> term.getMergeReportId().toString() + companyId + term.getIndexno().toString(), Function.identity()));
        }
        //处理合并报表未生成过该账期数据
        for (Long mergeReportId : mergeReportIdList) {
            for (Integer indexno : indexList) {
                String key = mergeReportId.toString() + companyId + indexno.toString();
                if (termSalaryMap.containsKey(key)) {
                    continue;
                }
                MergeSalaryReportTermSalary newTerm = new MergeSalaryReportTermSalary();
                newTerm.setCompanyId(companyId);
                newTerm.setReportState(ReportState.STARTED);
                newTerm.setIndexno(indexno);
                newTerm.setMergeReportId(mergeReportId);
                newTerm.setTermDate(termDate);
                newTerm.setYear(Integer.parseInt(DateUtils.formatDateStr(termDate, DateUtils.STANDARD_DATE_FORMAT_Y)));
                newTerm.setMonth(Integer.parseInt(DateUtils.formatDateStr(termDate, DateUtils.STANDARD_DATE_FORMAT_M)));
                mergeSalaryReportTermSalaryList.add(newTerm);
            }
        }
        logger.info("--------开始计算合并报表员工薪资数据");
        Iterable<MergeSalaryReportTermSalary> iterable = mergeSalaryReportTermSalaryRepository.save(mergeSalaryReportTermSalaryList);
        List<MergeSalaryReportTermSalary> termList = Lists.newArrayList(iterable);
        this.startCalMergeReportStaffSalary(companyId, termList, termDate);
    }

    @Transactional
    public void startCalMergeReportStaffSalary(String companyId, List<MergeSalaryReportTermSalary> termList, Date termDate) {
        if (CollectionUtils.isEmpty(termList) || termDate == null) {
            return;
        }
        List<Long> mergeReportIdList = termList.stream().map(MergeSalaryReportTermSalary::getMergeReportId).collect(Collectors.toList());
        //查询合并报表设置
        List<MergeSalaryReport> mergeSalaryReportList = mergeSalaryReportRepository.findByIdIn(mergeReportIdList);
        if (CollectionUtils.isEmpty(mergeSalaryReportList)) {
            logger.info("--------合并报表为空，无需计算");
            finishMergeReportCal(termList);
            return;
        }
        Map<Long, MergeSalaryReport> mergeSalaryReportMap = mergeSalaryReportList.stream().collect(Collectors.toMap(MergeSalaryReport::getId, Function.identity()));
        //查询合并报表所有薪资方案列表
        List<Long> salaryPlanIdList = Lists.newArrayList();
        mergeSalaryReportList.forEach(mergeSalaryReport -> {
            salaryPlanIdList.addAll(mergeSalaryReport.getSalaryPlanIdList());
        });
        //查询所有薪资方案该日期对应的历史账期数据
        int year = Integer.parseInt(DateUtils.formatDateStr(termDate, DateUtils.STANDARD_DATE_FORMAT_Y));
        int month = Integer.parseInt(DateUtils.formatDateStr(termDate, DateUtils.STANDARD_DATE_FORMAT_M));
        List<HistoryPayPeriod> historyPayPeriodList = historyPayPeriodRepository.findByCompanyIdAndSalaryPlanSalaryPlanIdInAndYearAndMonth(companyId, salaryPlanIdList, year, month);
        if (CollectionUtils.isEmpty(historyPayPeriodList)) {
            logger.info("--------历史账期数据为空，无需计算");
            finishMergeReportCal(termList);
            return;
        }
        //同一日期同一薪资方案不可存在多条账期记录，此处认为不存在重复key情况
        Map<Long, HistoryPayPeriod> historyPayPeriodMap = historyPayPeriodList.stream().collect(Collectors.toMap(historyPayPeriod -> historyPayPeriod.getSalaryPlan().getSalaryPlanId(), Function.identity()));
        //根据历史账期数据查询所有批次数据
        List<PayPeriodTerm> periodTermList = Lists.newArrayList();
        historyPayPeriodList.forEach(historyPayPeriod -> {
            periodTermList.addAll(historyPayPeriod.getTerms());
        });
        if (CollectionUtils.isEmpty(periodTermList)) {
            logger.info("--------批次数据为空，无需计算");
            finishMergeReportCal(termList);
            return;
        }
        //获取所有批次所有员工薪资数据
        List<Long> termIdList = periodTermList.stream().map(PayPeriodTerm::getId).collect(Collectors.toList());
        List<StaffPayPeriodTermSalary> salaryList = staffPayPeriodTermSalaryRepository.findByCompanyIdAndIdTermIdIn(companyId, termIdList);
        if (CollectionUtils.isEmpty(salaryList)) {
            logger.info("--------批次员工薪资信息为空，无需计算");
            finishMergeReportCal(termList);
            return;
        }
        Map<Long, List<StaffPayPeriodTermSalary>> salaryMap = Maps.newHashMap();
        salaryList.forEach(salary -> {
            Long termId = salary.getId().getTermId();
            List<StaffPayPeriodTermSalary> tempList = salaryMap.get(termId);
            if (CollectionUtils.isEmpty(tempList)) {
                tempList = Lists.newArrayList();
            }
            tempList.add(salary);
            salaryMap.put(termId, tempList);
        });
        //清除历史计算结果数据
        /*List<MergeReportStaffSalary> totalList = Lists.newArrayList();
        termList.forEach(term -> {
            List<MergeReportStaffSalary> reportStaffSalaryList = term.getStaffSalaryList();
            if (CollectionUtils.isNotEmpty(reportStaffSalaryList)) {
                totalList.addAll(reportStaffSalaryList);
                reportStaffSalaryList.clear();
            }
        });
        if (CollectionUtils.isNotEmpty(totalList)) {
            totalList.forEach(staffSalary -> {
                staffSalary.setTermSalary(null);
            });
            mergeReportStaffSalaryRepository.save(totalList);
            mergeReportStaffSalaryRepository.delete(totalList);
            entityManager.flush();
        }*/
        //开始组装所有合并报表数据结果
        for (MergeSalaryReportTermSalary term : termList) {
            //获取合并报表id
            Long reportId = term.getMergeReportId();
            MergeSalaryReport mergeSalaryReport = mergeSalaryReportMap.get(reportId);
            //根据合并报表获取合并报表中薪资方案中历史账期
            List<Long> containSalaryPlan = mergeSalaryReport.getSalaryPlanIdList();
            List<HistoryPayPeriod> historyPayPeriods = Lists.newArrayList();
            containSalaryPlan.forEach(id -> {
                if (historyPayPeriodMap.containsKey(id)) {
                    historyPayPeriods.add(historyPayPeriodMap.get(id));
                }
            });
            if (CollectionUtils.isEmpty(historyPayPeriods)) {
                continue;
            }
            //根据历史账期获取所有批次列表
            List<PayPeriodTerm> payPeriodTerms = Lists.newArrayList();
            historyPayPeriods.forEach(historyPayPeriod -> {
                List<PayPeriodTerm> terms = historyPayPeriod.getTerms();
                if (CollectionUtils.isNotEmpty(terms)) {
                    payPeriodTerms.addAll(terms);
                }
            });
            if (CollectionUtils.isEmpty(payPeriodTerms)) {
                continue;
            }
            //根据批次列表获取当前indexno批次列表(获取indexno对应的termList)
            List<Long> indexTermIds = Lists.newArrayList();
            payPeriodTerms.forEach(payPeriodTerm -> {
                if (payPeriodTerm.getTermIndex() == term.getIndexno()) {
                    indexTermIds.add(payPeriodTerm.getId());
                }
            });
            if (CollectionUtils.isEmpty(indexTermIds)) {
                continue;
            }
            //根据indexno批次列表获取批次所有员工薪资信息
            List<StaffPayPeriodTermSalary> staffSalaryList = Lists.newArrayList();
            indexTermIds.forEach(termId -> {
                if (salaryMap.containsKey(termId)) {
                    staffSalaryList.addAll(salaryMap.get(termId));
                }
            });
            if (CollectionUtils.isEmpty(staffSalaryList)) {
                continue;
            }
            //已获取所有信息，开始计算组装薪资信息
            getMergeSalaryTermData(companyId, term, mergeSalaryReport, historyPayPeriods, staffSalaryList);
        }
        finishMergeReportCal(termList);
        logger.info("--------合并报表数据计算完成");
    }

    //组装合并报表数据
    private void getMergeSalaryTermData(String companyId, MergeSalaryReportTermSalary term, MergeSalaryReport mergeSalaryReport, List<HistoryPayPeriod> historyPayPeriods, List<StaffPayPeriodTermSalary> staffSalaryList) {
        //计算人员列表
        List<String> staffIdList = this.getStaffIdList(mergeSalaryReport, historyPayPeriods);
        if (CollectionUtils.isEmpty(staffIdList)) {
            logger.info("--------员工列表为空");
            return;
        }
        //获取表头
        List<SalaryFieldSnapshot> fieldList = mergeSalaryReport.getMergeSalaryField().getFields();
        SalaryHeader header = this.getHead(fieldList);
        term.setSalaryHeader(header);
        //根据计算出的人员列表获取相应薪资信息
        if (CollectionUtils.isEmpty(staffSalaryList)) {
            logger.info("--------员工列表为空");
            return;
        }
        Map<String, List<StaffPayPeriodTermSalary>> salaryMap = getStaffSalaryMap(staffSalaryList);
        List<MergeReportStaffSalary> reportStaffSalaryList = term.getStaffSalaryList();
        if (reportStaffSalaryList == null) {
            reportStaffSalaryList = Lists.newArrayList();
        } else {
            reportStaffSalaryList.clear();
        }
        for (String staffId : staffIdList) {
            List<StaffPayPeriodTermSalary> salaryList = salaryMap.get(staffId);
            if (CollectionUtils.isEmpty(salaryList)) {
                return;
            }
            MergeReportStaffSalary staffSalary = calStaffSalary(staffId, salaryList, companyId, fieldList, term);
            reportStaffSalaryList.add(staffSalary);
        }
        term.setStaffSalaryList(reportStaffSalaryList);
    }

    private MergeReportStaffSalary calStaffSalary(String staffId, List<StaffPayPeriodTermSalary> salaryList, String companyId, List<SalaryFieldSnapshot> fieldList, MergeSalaryReportTermSalary term) {
        MergeReportStaffSalary staffSalary = new MergeReportStaffSalary();
        staffSalary.setId(new StaffSalaryTermId(term.getId(), staffId));
        staffSalary.setCompanyId(companyId);
        staffSalary.setTermSalary(term);
        //计算汇总信息
        calSalaryData(salaryList, fieldList, staffSalary);
        return staffSalary;
    }

    //计算汇总/分段数据信息
    private void calSalaryData(List<StaffPayPeriodTermSalary> salaryList, List<SalaryFieldSnapshot> fieldList, MergeReportStaffSalary staffSalary) {
        if (CollectionUtils.isEmpty(fieldList) || CollectionUtils.isEmpty(salaryList)) {
            return;
        }
        List<String> fieldCodeList = fieldList.stream().map(SalaryFieldSnapshot::getCode).collect(Collectors.toList());
        StaffSalarySnapshot mergeSummaryData = new StaffSalarySnapshot();
        List<StaffSalarySnapshot> phasedData = Lists.newArrayList();
        Map<String, DynamicCell> summary = Maps.newLinkedHashMap();
        StaffSalarySnapshotListWrapper mergePhasedData = new StaffSalarySnapshotListWrapper();
        for (String fieldCode : fieldCodeList) {
            DynamicCell mergeCell = new DynamicCell();
            BigDecimal value = null;
            for (StaffPayPeriodTermSalary salary : salaryList) {
                if (salary == null || salary.getSummarizedData() == null || CollectionUtils.isEmpty(salary.getSummarizedData().getData())) {
                    continue;
                }
                mergeSummaryData.setStartOn(salary.getSummarizedData().getStartOn());
                mergeSummaryData.setEndOn(salary.getSummarizedData().getEndOn());
                Map<String, DynamicCell> data = salary.getSummarizedData().getData();
                if (data.containsKey(fieldCode)) {
                    DynamicCell cell = data.get(fieldCode);
                    if (cell != null && StringUtils.isNotBlank(cell.getCellValue())) {
                        BigDecimal cellValue = new BigDecimal(cell.getCellValue());
                        if (value == null) {
                            value = cellValue;
                        } else {
                            value = value.add(cellValue);
                        }
                    }
                }
            }
            if (value != null) {
                mergeCell.setCellValue(Double.toString(value.doubleValue()));
            }
            summary.put(fieldCode, mergeCell);
        }
        salaryList.forEach(staffPayPeriodTermSalary -> {
            if (staffPayPeriodTermSalary.getPhasedData() != null && CollectionUtils.isNotEmpty(staffPayPeriodTermSalary.getPhasedData().getPhasedData())) {
                phasedData.addAll(staffPayPeriodTermSalary.getPhasedData().getPhasedData());
            }
        });
        mergeSummaryData.setData(summary);
        mergePhasedData.setPhasedData(phasedData);
        staffSalary.setSummarizedData(mergeSummaryData);
        staffSalary.setPhasedData(mergePhasedData);
    }

    //计算当前合并报表人员列表
    private List<String> getStaffIdList(MergeSalaryReport mergeSalaryReport, List<HistoryPayPeriod> historyPayPeriods) {
        List<String> staffIds = Lists.newArrayList();
        List<HistorySalaryPlan> historySalaryPlanList = Lists.newArrayList();
        historyPayPeriods.forEach(historyPayPeriod -> {
            HistorySalaryPlan historySalaryPlan = historyPayPeriod.getSalaryPlan();
            if (historySalaryPlan != null) {
                historySalaryPlanList.add(historySalaryPlan);
            }
        });
        Map<Long, HistorySalaryPlan> salaryPlanMap = historySalaryPlanList.stream().collect(Collectors.toMap(HistorySalaryPlan::getSalaryPlanId, Function.identity()));
        if (MergeSalaryReport.JoinType.LEFT_JOIN.equals(mergeSalaryReport.getJoinType())) {//以基准表中员工
            Long salaryPlanId = mergeSalaryReport.getJoinSalaryPlanId();
            if (salaryPlanId == null || !salaryPlanMap.containsKey(salaryPlanId)) {
                //无基准表或者基准表无历史数据，直接返回
                return Lists.newArrayList();
                //throw new Ihr360Exception(null, "合并基准薪资方案不可为空");
            }
            HistorySalaryPlan historySalaryPlan = salaryPlanMap.get(salaryPlanId);
            if (checkHistoryStaffIsNotEmpty(historySalaryPlan)) {
                staffIds = historySalaryPlan.getStaffs().getStaffIdList();
            }
        } else if (MergeSalaryReport.JoinType.INNER_JOIN.equals(mergeSalaryReport.getJoinType())) { //取各张表都有的员工
            //所有员工
            List<String> staffList = Lists.newArrayList();
            historySalaryPlanList.forEach(historySalaryPlan -> {
                if (checkHistoryStaffIsNotEmpty(historySalaryPlan)) {
                    staffList.addAll(historySalaryPlan.getStaffs().getStaffIdList());
                }
            });
            //每个方案中的员工
            List<List<String>> eachStaffList = Lists.newArrayList();
            for (HistorySalaryPlan historySalaryPlan : historySalaryPlanList) {
                if (!checkHistoryStaffIsNotEmpty(historySalaryPlan)) {
                    continue;
                }
                eachStaffList.add(historySalaryPlan.getStaffs().getStaffIdList());
            }
            for (String salaryPlanStaff : staffList) {
                boolean isContain = true;
                for (List<String> staffList1 : eachStaffList) {
                    if (!staffList1.contains(salaryPlanStaff)) {
                        isContain = false;
                    }
                }
                if (isContain && !staffIds.contains(salaryPlanStaff)) {
                    staffIds.add(salaryPlanStaff);
                }
            }
        } else {//取各张表中所有的员工
            for (HistorySalaryPlan historySalaryPlan : historySalaryPlanList) {
                if (!checkHistoryStaffIsNotEmpty(historySalaryPlan)) {
                    continue;
                }
                List<String> staffList = historySalaryPlan.getStaffs().getStaffIdList();
                for (String staffId : staffList) {
                    if (!staffIds.contains(staffId)) {
                        staffIds.add(staffId);
                    }
                }
            }
        }
        return staffIds;
    }

    private Boolean checkHistoryStaffIsNotEmpty(HistorySalaryPlan salaryPlan) {
        if (salaryPlan != null && salaryPlan.getStaffs() != null && CollectionUtils.isNotEmpty(salaryPlan.getStaffs().getStaffIdList())) {
            return true;
        } else {
            return false;
        }
    }

    private Map<String, List<StaffPayPeriodTermSalary>> getStaffSalaryMap(List<StaffPayPeriodTermSalary> staffSalaryList) {
        Map<String, List<StaffPayPeriodTermSalary>> salaryMap = Maps.newHashMap();
        if (CollectionUtils.isEmpty(staffSalaryList)) {
            return salaryMap;
        }
        staffSalaryList.forEach(salary -> {
            String staffId = salary.getStaffId();
            List<StaffPayPeriodTermSalary> tempList = salaryMap.get(staffId);
            if (CollectionUtils.isEmpty(tempList)) {
                tempList = Lists.newArrayList();
            }
            tempList.add(salary);
            salaryMap.put(staffId, tempList);
        });
        return salaryMap;
    }

    //修改状态
    private void finishMergeReportCal(List<MergeSalaryReportTermSalary> termList) {
        termList.forEach(mergeSalaryReportTermSalary -> {
            mergeSalaryReportTermSalary.setReportState(ReportState.FINISHED);
            String remark = "报表生成时间" + DateUtils.formatDateStr(new Date(), "yyyy年MM月dd日");
            mergeSalaryReportTermSalary.setRemark(remark);
        });
        mergeSalaryReportTermSalaryRepository.save(termList);
    }

    /**
     * 解析表头
     */
    private SalaryHeader getHead(List<SalaryFieldSnapshot> salaryFieldSnapshotList) {
        Map<String, SalaryFieldEntity> head = Maps.newLinkedHashMap();

        head.put(HistorySalaryPlanServiceImpl.EXCEL_FIELD_NAME, new SalaryFieldEntity(HistorySalaryPlanServiceImpl.EXCEL_FIELD_NAME, SyncedBasicStaffInfo.Field.staffName, true));
        head.put(HistorySalaryPlanServiceImpl.DEPARTMENT_NAME, new SalaryFieldEntity(HistorySalaryPlanServiceImpl.DEPARTMENT_NAME, SyncedBasicStaffInfo.Field.departmentName, true));
        head.put(HistorySalaryPlanServiceImpl.EXCEL_FIELD_MOBILE_NO, new SalaryFieldEntity(HistorySalaryPlanServiceImpl.EXCEL_FIELD_MOBILE_NO, SyncedBasicStaffInfo.Field.mobileNo, true));


        if (CollectionUtils.isNotEmpty(salaryFieldSnapshotList)) {
            salaryFieldSnapshotList.forEach(field -> {
                SalaryFieldEntity entity = new SalaryFieldEntity();
                entity.setFieldName(field.getName());
                entity.setColumnName(field.getCode());
                entity.setSource(field.getSource());
                entity.setReadOnly(field.getSource() != FieldSource.INPUT);
                entity.setFormula(field.getFormula());
                SalaryFieldValueType type = field.getValueType();
                switch (type) {
                    case NUMBER:
                        entity.setType("DOUBLE");
                        break;
                    case DATE:
                    case TIME:
                    case DATETIME:
                        entity.setType("DATE");
                        entity.setRegexp(type.getPattern());
                        break;
                    case ARRAY:
                        break;
                    default:
                        entity.setType("STRING");
                        break;
                }
                head.put(field.getName(), entity);
            });
        }
        SalaryHeader salaryHeader = new SalaryHeader();
        salaryHeader.setHeadMap(head);
        return salaryHeader;
    }


}
